/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package gene.core.util;

import gene.core.*;
//import gene.core.util.Surface;
import javax.microedition.lcdui.Image;
/**
 *Sprite sheet controler , version 2.0
 * @author vlm
 */

public class Sprite {

  	/**
	 * No transform is applied to the Sprite.
	 * This constant has a value of <code>0</code>.
	 */
	public static final int TRANS_NONE = 0;
	/**
	 * Causes the Sprite to appear rotated clockwise by 90 degrees.
	 * This constant has a value of <code>5</code>.
	 */
	public static final int TRANS_ROT90 = 5;
	/**
	 * Causes the Sprite to appear rotated clockwise by 180 degrees.
	 * This constant has a value of <code>3</code>.
	 */
	public static final int TRANS_ROT180 = 3;
	/**
	 * Causes the Sprite to appear rotated clockwise by 270 degrees.
	 * This constant has a value of <code>6</code>.
	 */
	public static final int TRANS_ROT270 = 6;
	/**
	 * Causes the Sprite to appear reflected about its vertical
	 * center.
	 * This constant has a value of <code>2</code>.
	 */
	public static final int TRANS_MIRROR = 2;
	/**
	 * Causes the Sprite to appear reflected about its vertical
	 * center and then rotated clockwise by 90 degrees.
	 * This constant has a value of <code>7</code>.
	 */
	public static final int TRANS_MIRROR_ROT90 = 7;
	/**
	 * Causes the Sprite to appear reflected about its vertical
	 * center and then rotated clockwise by 180 degrees.
	 * This constant has a value of <code>1</code>.
	 */
	public static final int TRANS_MIRROR_ROT180 = 1;
	/**
	 * Causes the Sprite to appear reflected about its vertical
	 * center and then rotated clockwise by 270 degrees.
	 * This constant has a value of <code>4</code>.
	 */
	public static final int TRANS_MIRROR_ROT270 = 4;

    short  [] x_y_h_w = {0,0,0,0};
    short  [] maxX_maxY_maxFrame = {0,0,0};
    //short [] posX_posY_frame = {0,0,0};
    public  Image   img          =  null;
    //private int     W            =  0;
    //private int     H            =  0;
    private int     frame        =  0;
    //private int     X            =  0;
    //private int     Y            =  0;
    private int     maxX         =  0;
    private int     maxY         =  0;
    //private Image   tmp          =  null;
    private int     ticks        =  0;
    private int  [] animation    =  null;
    private int     maxFrame     = -1;
    private int     index        =  0;
    private int     posX         =  0;
    private int     posY         =  0;
    private boolean hasAnimation     = false;
    private int     transformation   = -1;
    /**
     *
     * @param img
     * @param frameW
     * @param frameH
     */
    public Sprite(Image _img, int frameW, int frameH){//, int delay) {
        
        if(img==null){
            new Exception("Sprite Image null pointer");
        }
        //System.out.println(" _img "+img+" W "+frameW+" H "+frameH);
        img = _img;
        x_y_h_w[3]      = (short) frameW ; //W = frameW;
        x_y_h_w[2]      = (short) frameH;//H = frameH;
        frame = 0;
        maxX = (img.getWidth() /  /*W*/ x_y_h_w[3] );
        maxY = (img.getHeight() / /*H*/ x_y_h_w[2]);
        maxFrame = maxX * maxY;
        ticks = 0;
    }

        /**
     *
     * @param img
     * @param frameW
     * @param frameH
     */
/*    public Sprite(Surface surface, int frameW, int frameH){//, int delay) {

        if(surface==null){
            new Exception("Sprite Image null pointer");
        }

        Image _img = Surface.surfaceToImage(surface);
        
        //System.out.println(" _img "+img+" W "+frameW+" H "+frameH);
        img = _img;
        x_y_h_w[3]      = (short) frameW ; //W = frameW;
        x_y_h_w[2]      = (short) frameH;//H = frameH;
        frame = 0;
        maxX = (img.getWidth() /  /*W* x_y_h_w[3] );
        maxY = (img.getHeight() / /*H* x_y_h_w[2]);
        maxFrame = maxX * maxY;
        ticks = 0;
    }*/


    /**
     * Cria uma animação com os quadros selecionados
     * @param frames
     * Obs : se frames for iqual a null a classe retornará ao comportamento original;
     *
    public void setAnimation(short[] frames) {
        this.animation = null;
        this.animation = frames;
        frame = 1;
        TICKS = 0;
        if(DIRECT_MODE){this.maxFrame=frames.length;}
        print = true;
    }*/
  public void setAnimation(int [] animation){
   hasAnimation=true;
   animation = animation;
  }

  public void nextFrame() {
        if(!hasAnimation){
        //frame++;
        if (++frame > maxFrame -1 ) {
            frame = 1;
        }
        }
        else
        {
          //index--;
          if (--index < 0) {
              index = animation.length - 1;
          }
        }

    }

  public void antFrame() {
        if(!hasAnimation){
          //frame--;
          if (--frame < 1) {
              frame = maxFrame - 1;
          }
        }
        else
        {
          //index--;
          if (--index < 0) {
              index = animation.length - 1;
          }
        }
    }

    /***
     *
     */
    public void setPosition(int posx, int posy) {
        posX = posx;
        posY = posy;
    }

    
    /**
     * imprime em tela o quadro atual na posição x,y
     */
    public void paint(int _transformation) {
        transformation = _transformation;
        
    if(!hasAnimation){
        Core._image = null;
            getImage(frame, transformation);
                   
    }else{
         if(animation != null)
         {
            getImage(animation[index],transformation);
      }
    }
    Core.graphicDevice.buffer(Core._image , posX , posY );
    
    }

    /**
     * set o quadro atual a ser impresso em tela;
     * @param frame
     * caso o frame não esteja na faixa entre 0(zero) e o (frame máximo) , o frame será setado como 1;
     */
    public void setFrame(int frame) {
       
        if (frame <= 0) {

            } else {

                if(frame-1 > maxFrame){
                    frame = 0;

                }else{

                    if(frame-1  < maxFrame){
                        this.frame = --frame;//-1;
                    }
                }
            }

    }

    public int getFrameW() {
        return x_y_h_w[3];
    }

    public int getFrameH() {
        return x_y_h_w[2];
    }

    public void setImage(Image img){
        img = img;
    }

    public Image getImage(){
        return img;
    }

    public int getPositionX(){
        return posX;
    }
    
    public int getPositionY(){
        return posY;
    }

    public int getFrame(){
        return frame;
    }

    public void getFrame(int frame){
        frame=frame;
    }


    /**
     *
     * @param sprite
     * @return
     */
    public boolean collidsWith(Sprite sprite){

    if(sprite.getPositionX() + sprite.getFrameW() < x_y_h_w[0] )
	return false;	//just checking if their
	
    if(sprite.getPositionX() > x_y_h_w[0] + x_y_h_w[3]/*X + W*/)
	return false;	//bounding boxes even touch

	if(sprite.getPositionY() + sprite.getFrameH() < x_y_h_w[1] /*Y*/)
	return false; //

	if(sprite.getPositionY() > x_y_h_w[2] /*Y + H*/)
	return false; // 

    return true; // collidiu

    }

     public static Image changeColor(int[] colorRef, int[] newColor, Image image) {

        //os arrays nao podem ter tamanhos diferrentes
        if ((colorRef.length - newColor.length) != 0) {
            return null;
        }
        Core._image = null;
        int w = image.getWidth();
        int h = image.getHeight();
        int size = w * h;
        int colorSize = colorRef.length;
        int[] data = new int[size];
        int i = size;
        int j = colorSize;

        image.getRGB(data, 0, 0, 0, 0, w, h);

        for (; --i > 0;) {
            for (; --j > 0;) {
                //se forem iguais
                if ((colorRef[j] - data[i]) == 0) {
                    data[i] = newColor[j];
                }
            }
        }

        Core._image = Image.createRGBImage(data, w, h, true);

        return Core._image;
    }


    /**
     * Changes size of bitmap.
     * @param sourceImage source image.
     * @param newWidth width of new image.
     * @param newHeight height of new image.
     * @return scaled image.
     */
    private Image scaleImage(Image sourceImage, int newWidth, int newHeight) {

        int oldWidth = sourceImage.getWidth();
        int oldHeight = sourceImage.getHeight();

        int[] inputData = new int[oldWidth * oldHeight];
        sourceImage.getRGB(inputData, 0, oldWidth, 0, 0, oldWidth, oldHeight);

        int[] outputData = new int[newWidth * newHeight];

        int YD = (oldHeight / newHeight - 1) * oldWidth;
        int YR = oldHeight % newHeight;
        int XD = oldWidth / newWidth;
        int XR = oldWidth % newWidth;
        int outOffset = 0;
        int inOffset = 0;

        for (int y = newHeight, YE = 0; --y > 0;) {
            for (int x = newWidth, XE = 0; --x > 0;) {
                outputData[outOffset++] = inputData[inOffset];
                inOffset += XD;
                XE += XR;
                if (XE >= newWidth) {
                    XE -= newWidth;
                    inOffset++;
                }
            }
            inOffset += YD;
            YE += YR;
            if (YE >= newHeight) {
                YE -= newHeight;
                inOffset += oldWidth;
            }
        }
        return Image.createRGBImage(outputData, newWidth, newHeight, false);
    }


    public Image getImage(int frame ,int transformation){
               /*Y*/ x_y_h_w[1] = (short) (this.frame / maxX);
               /*X*/ x_y_h_w[0] = (short) (this.frame % maxX);
                   //Core._image = Image.createImage ( img , X * W , Y * H , W , H , transformation );
                   Core._image = Image.createImage ( img , x_y_h_w[0] * x_y_h_w[3] , x_y_h_w[1] * x_y_h_w[2] , x_y_h_w[3] , x_y_h_w[2] , transformation );
                   return Core._image;
    }

   /**
    * get the reffer pixel color of current frame.
    * @param x
    * @param y
    * @return
    */
   public int getPixel(int x, int y){

       //int tmp [] = new int[W*H];
       int tmp [] = new int[ x_y_h_w[3] * x_y_h_w[2] ];
       //x+(y*W);

       if ( !hasAnimation ) {

           Core._image = getImage(frame, transformation);
       
       } else {

           Core._image = getImage(animation[index], transformation);

       }
          Core._image.getRGB(tmp,0, frame, 0 , 0 ,Core._image.getWidth(), Core._image.getHeight());
          Core._image = null;

       try{
            //return tmp[x + ( y * W)];
            return tmp[x + ( y * x_y_h_w[3])];
       }catch(Exception e){
           return -1;
       }
       
   }
    


}
